#include "U2Codec.h"

#include "U2Exception.h"


U2EG_NAMESPACE_USING


std::map< U2String, U2Codec * > U2Codec::s_mapCodecs;

/*
U2Codec::U2Codec(void)
{
}
*/

U2Codec::~U2Codec(void)
{
}




U2StringVector U2Codec::getExtensions(void)
{
    U2StringVector result;
    result.reserve(s_mapCodecs.size());
    CodecList::const_iterator i;
    for (i = s_mapCodecs.begin(); i != s_mapCodecs.end(); ++i)
    {
        result.push_back(i->first);
    }
    return result;
}

U2Codec* U2Codec::getCodec(const U2String& extension)
{
    U2String lwrcase = extension;
    U2StringUtil::toLowerCase(lwrcase);
    CodecList::const_iterator i = s_mapCodecs.find(lwrcase);
    if (i == s_mapCodecs.end())
    {
        U2_EXCEPT(U2Exception::ERR_ITEM_NOT_FOUND, 
            "Cannot find codec for extension " + extension,
            "U2Codec::getCodec");
    }

    return i->second;
}

U2Codec* U2Codec::getCodec(char *magicNumberPtr, size_t maxbytes)
{
    for (CodecList::const_iterator i = s_mapCodecs.begin(); 
        i != s_mapCodecs.end(); 
        ++i)
    {
        U2String ext = i->second->magicNumberToFileExt(magicNumberPtr, maxbytes);
        if (!ext.empty())
        {
            // check codec type matches
            // if we have a single codec class that can handle many types, 
            // and register many instances of it against different types, we
            // can end up matching the wrong one here, so grab the right one
            if (ext == i->second->getType())
                return i->second;
            else
                return getCodec(ext);
        }
    }

    return 0;
}